/* 
 * File:   Servidor.cpp
 * Author: max
 * 
 * Created on October 19, 2012, 12:31 AM
 */

#include "server_Servidor.h"
#include "server_FileService.h"

using namespace TP::Comunicacion;

#define PROCESO_AUTENTICACION 1

Servidor::Servidor(ServerConfFileManager *pConfiguracion){

    _configuracion = pConfiguracion;
    _conexion = NULL;
    _ecoService = NULL;
    _fileService = NULL;
    _repositorio = NULL;
    _procesoAutenticacion = NULL;

}

Servidor::~Servidor() {
    
    // Doy de baja la conexion.
    if (NULL != _conexion)
    {
        delete _conexion;
        delete _procesoAutenticacion;
        delete _ecoService;
        delete _fileService;
        delete _repositorio;
    }
    
}

void Servidor::Iniciar() throw (Excepcion&){
    try
    {
        /* Instancia los procesos.
         */
        _procesoAutenticacion = new ProcesoAutenticacion(PROCESO_AUTENTICACION, (IAutenticacionManejadorEvento*) this, USUARIOS_DB_RUTA_ARCHIVO);
        
        /* Instancia los servicios.
         */
        _ecoService = new EcoService();
        _fileService = new FileService(_configuracion->GetPathAU());
        _repositorio = new Repositorio(_configuracion->GetPathAU());
        
        /* Instancia la conexion.
         */
        _conexion = new Conexion (_configuracion->GetPuertoServidor(), (IManejadorConexionEvento*)_procesoAutenticacion);
        
        /* Ejecuta la secuencia de inicio.
         */
        _conexion->Iniciar();
        _procesoAutenticacion->Iniciar();
        _fileService->Iniciar();
        _ecoService->Iniciar();
    }
    catch (Excepcion& pEx)
    {
        pEx.expandirMensaje("No se puede iniciar el sevidor.");
        throw;
    }
}

void Servidor::Finalizar() throw (Excepcion&){
    try
    {
        // Doy de baja la conexion a fin de evitar nuevas sesiones.
        _conexion->Finalizar();
        
        // Doy de baja las sesiones activas.
        for (vector<Sesion*>::size_type cur = 0; cur < _sesiones.size(); cur++)
        {
            try
            {
                _sesiones[cur]->Finalizar();
            }
            catch (Excepcion& pEx)
            {
//                *(this->log) << pEx.what() << endl;
            }
            delete _sesiones[cur];
        }
        _sesiones.clear();

    }
    catch (Excepcion& pEx)
    {
        pEx.expandirMensaje("No se puede finializar correctamente el sevidor.");
        throw;
    }
}

void Servidor::notificarNuevaSesionEvento (Sesion* pSesion){
    
    try
    {
        if (pSesion)
        {
            // Se configuran los manejadores de mensaje de la sesion.
            pSesion->agregarManejadorSesionEvento(this);
            
            pSesion->agregarMensajeEntranteManejador((IMensajeEntranteManejador*)this->_ecoService);
            pSesion->agregarMensajeEntranteManejador((IMensajeEntranteManejador*)this->_fileService);
            
            // Se debe iniciar la escucha de mensajes de la sesion.
            pSesion->Iniciar();
            
            // Se debe registrar la sesion en la lista de sesiones del servidor.
            _sesiones.push_back(pSesion);
        }
    }
    catch (Excepcion& pEx)
    {
        std::cout << "No se puede manejar la nueva sesion.  " << pEx.what() << endl;
    }
}

void Servidor::eventoConexionFinalizada (IEnviante* pEnviante, const string& pMensaje){
    cout << "Servidor.eventoConexionFinalizada no implementado." << endl;
    exit (10);
}

void Servidor::eventoErrorComunicacion (IEnviante* pEnviante, const string& pMensaje ){
    cout << "Servidor.eventoErrorComunicacion no implementado." << endl;
    exit (10);
}

void Servidor::notificarErrorAutenticacionEvento (Sesion* pSesion) {
    try
    {
        _conexion->Finalizar();
    }
    catch (Excepcion &ex)
    {
    }
    
    cout << "Servidor.notificarErrorAutenticacionEvento no implementado." << endl;
    exit (10);
}